<?php
/**
 * Created by PhpStorm.
 * User: Administrator
 * Date: 2023/10/17
 * Time: 17:24
 */

namespace app\logic\index\douyin;



use app\common\lib\DouYinOpenApp;
use app\logic\BaseLogic;

class DouYinAppLogic extends BaseLogic
{
    protected static $instance;

    public function __construct()
    {
        parent::__construct();
    }

    public static function getInstance()
    {
//        if (is_object(self::$instance)) {
//            return self::$instance;
//        }

        return  new self();
    }

    public function createAgent()
    {
        $result = DouYinOpenApp::getInstance()->createAgent();
        $result['data']['agent_id'] = (string) $result['data']['agent_id'];
        return $result;
    }

    public function getTaskId($param)
    {
        $appid     = $param['appid'];
        $startTime = strtotime('-6 day');
        $endTime   = time();
        $result    = DouYinOpenApp::getInstance()->searchTaskId($appid, $startTime, $endTime);
        return $result;
    }

    public function getTaskDetail()
    {
        $result = DouYinOpenApp::getInstance()->searchTaskInfo();
        return $result;
    }

    public function getCooperateLink()
    {
        $agentid = '7291918592630276136';
        $appid   = null;
        $taskid  = '7290754441500721210';
        $userSn  = (string)request()->curUserId;
        $result  = DouYinOpenApp::getInstance()->getCooperateLink($agentid, $appid, $taskid, $userSn);

        return $result;
    }

    public function searchBindRecord()
    {
        $agentid = '7291918592630276136';
        $userSn  = (string)request()->curUserId;
        $result  = DouYinOpenApp::getInstance()->searchBindRecord(1, 10, $agentid, null, $userSn);

        return $result;
    }

    public function getDouYinUserInfoByCode($param)
    {
        $lock = Common::setnx('getDouYinUserInfoByCode_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }

        //todo 1 获取accessToken和保存accessToken
        $data = $this->saveDouyinAccessToken($param);

        //todo 2 判断是否已经授权合作或者授权到那一步了
        $where = ['open_id'=>$data['open_id']];
        $filed = ['douyin_user_id','avatar','nickname','mobile','user_sn','douyin_uid','fans_number','status'];
        $first = DouyinUser::getInstance()->getWhere($where)->first($filed);
        if($first){
            $count = UserModel::getInstance()->getWhere(['user_sn'=>$first['user_sn'],'isdel'=>0])->count();
            if($count && $first['status']>1 && $first['user_sn']!=request()->curUserId){
                throw new IndexException(4020,'该抖音号已被其他用户绑定');
            }

            $cooperateFirst = DouyinUserCooperate::getInstance()->getWhere(['douyin_user_id'=>$first['douyin_user_id'],'isdel'=>0])->first();
            if($cooperateFirst && $cooperateFirst['status']==3){
                throw new IndexException(4020,'该抖音号已授权合作');
            }elseif($cooperateFirst && $cooperateFirst['status']==2){
                throw new IndexException(4020,'该抖音号已提交授权,等待审核');
            }elseif($cooperateFirst && $cooperateFirst['status']==1){
                $stepStatus = $this->checkAuthorizeStatus($cooperateFirst);
                $first['cooperate_id'] = $cooperateFirst['cooperate_id'];
                $first['step'] = (int)($stepStatus['status']+2);
                return $first;
            }
        }

        //todo 3 没有申请过的，需要获取抖音用户公开信息
        $douYinUserData = DouYinOpenApp::getInstance()->getUserData(['open_id'=>$data['open_id']]);
        if(!empty($douYinUserData['data']['error_code'])){
            throw new IndexException(4020,'获取用户信息失败');
        }
        //获取抖音粉丝画像的粉丝数据
        //$douYinUserFansData = DouYinOpenApp::getInstance()->getUserFansData(['open_id'=>$data['open_id']]);
        //$douYinUserData['data']['fans_number'] = $douYinUserFansData['data']['fans_data']['all_fans_num']??0;
        $this->saveDouYinUserData($douYinUserData);

        $where = ['open_id'=>$data['open_id'],'user_sn'=>request()->curUserId];
        $filed = ['douyin_user_id','avatar','nickname','mobile','douyin_uid','fans_number','status'];
        $first = DouyinUser::getInstance()->getWhere($where)->first($filed);
        $first && $first['step'] = 1;
        $first && $first['cooperate_id'] = 0;

        return $first ? $first : [];
    }

    protected function saveDouyinAccessToken($param)
    {
        $data = DouYinOpenApp::getInstance()->getAccessTokenByCode($param);
        $source = 1;
        if(!empty($param['state']) && strpos($param['state'],'kol')===0){
            $userSn = substr($param['state'],3);
            $source = 2;
        }else{
            $userSn = request()->curUserId;
        }

        if(empty($data['access_token'])){
            throw new IndexException(4020,'授权失败');
        }

        $insert = [
            "code"=>$param['code'],
            "access_token"=>$data['access_token']??'',
            "captcha"=>$data['captcha']??'',
            "desc_url"=>$data['desc_url']??'',
            "description"=>$data['description']??'',
            "error_code"=>$data['error_code']??'',
            "expires_in"=>$data['expires_in']??'0',
            "log_id"=>$data['log_id']??'',
            "open_id"=>$data['open_id']??'',
            "refresh_expires_in"=>$data['refresh_expires_in']??'0',
            "refresh_token"=>$data['refresh_token']??'',
            "scope"=>$data['scope']??'',
            "expires_time"=>time()+$data['expires_in']-43200,
            "refresh_expires_time"=>time()+$data['refresh_expires_in']-43200,
            "user_sn"=>$userSn,
            "code_id"=>0,
            "source"=>$source,
            "createtime"=>date('Y-m-d H:i:s'),
            "platform"=>2,
        ];
        $result = DouyinAccessToken::getInstance()->insertGetId($insert);

        return $data;
    }
    protected function saveDouYinUserData($result)
    {
        $first = DouyinUser::getInstance()->getWhere(['open_id'=>$result['data']['open_id']])->first();
        if($first){
            !empty($result['data']['avatar']) && $first->avatar = $result['data']['avatar'];
            !empty($result['data']['nickname']) && $first->nickname = $result['data']['nickname'];
            !empty($result['data']['encrypt_mobile']) && $first->encrypt_mobile = $result['data']['encrypt_mobile'];
            !empty($result['data']['e_account_role']) && $first->e_account_role = $result['data']['e_account_role'];
            !empty($result['data']['union_id']) && $first->union_id = $result['data']['union_id'];
            !empty($result['data']['client_key']) && $first->client_key = $result['data']['client_key'];
            !empty($result['data']['mobile']) && $first->mobile = $result['data']['mobile'];
            !empty($result['data']['fans_number']) && $first->mobile = $result['data']['fans_number'];
            $first->user_sn = request()->curUserId;
            $first->updatetime = date('Y-m-d H:i:s');
            $first->is_authorize = 1;
            return $first->save();
        }else{
            $insert = [
                'avatar'=>$result['data']['avatar']??'',
                'nickname'=>$result['data']['nickname']??'',
                'open_id'=>$result['data']['open_id']??'',
                'e_account_role'=>$result['data']['e_account_role']??'',
                'encrypt_mobile'=>$result['data']['encrypt_mobile']??'',
                'union_id'=>$result['data']['union_id']??'',
                'client_key'=>$result['data']['client_key']??'',
                'createtime'=>date('Y-m-d H:i:s'),
                'mobile'=>!empty($result['data']['mobile']) ? $result['data']['mobile'] : '',
                'fans_number'=>!empty($result['data']['fans_number']) ? $result['data']['fans_number'] : '0',
                'user_sn'=>request()->curUserId,
                'is_authorize'=>1,
            ];
           return DouyinUser::getInstance()->insert($insert);
        }
    }

    public function getBindStatus($param)
    {
        $first = DouyinUserCooperate::getInstance()->getWhere(['cooperate_id'=>$param['cooperate_id']])->first();
        if($first==false){
            throw new IndexException(4020,'合作数据不存在');
        }
        return $this->checkAuthorizeStatus($first);
    }

    public function checkAuthorizeStatus($first)
    {
        //检查当前结算是否已经绑定
        $count = DB::table('live_baiyin_user_settlement_bind')->where(['user_id'=>$first['douyin_uid'],'bind_status'=>6])->count();
        if($count){
            return ['status'=>2];
        }

        //获取结算绑定列表
        $result = MCNApply::getInstance()->checkSettlementBingTrue();
        if(!empty($result['data'])){
            foreach($result['data'] as $val){
                $insertParam = [
                    'table'=>'live_baiyin_user_settlement_bind',
                    'keyid'=>'user_settlement_bind_id',
                    'update_fields'=>['user_id'],
                    'attributes'=>$val,
                ];
                $this->autoCreateTableAndInsertData($insertParam);

                //如果已经确认则这里会找到user_id
                if($first['douyin_uid']==$val['user_id']){
                    return ['status'=>2];
                }
            }
        }

        //检查当前账号是否已经绑定
        $count = DB::table('live_baiyin_user_account')->where(['user_id'=>$first['douyin_uid'],'status'=>5])->count();
        if($count){
            return ['status'=>1];
        }

        //获取绑定账号列表
        $result = MCNApply::getInstance()->checkApplyBingTrue();
        if(!empty($result['data'])){
            foreach($result['data'] as $val){
                $insertParam = [
                    'table'=>'live_baiyin_user_account',
                    'keyid'=>'user_account_id',
                    'update_fields'=>['user_id'],
                    'attributes'=>$val,
                ];
                $this->autoCreateTableAndInsertData($insertParam);

                //如果已经确认则这里会找到user_id
                if($first['douyin_uid']==$val['user_id']){
                    return ['status'=>1];
                }
            }
        }

        return ['status'=>0];
    }

    public function sendDouYinAuthCode($param)
    {
        $lock = Common::setnx('sendDouYinAuthCode_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }
//        if(Common::checkMobile($param['mobile'])==false){
//            throw new IndexException(4020,'抖音手机号码错误');
//        }
        $where = [
            'user_sn'=>request()->curUserId,
            'douyin_user_id'=>$param['douyin_user_id'],
        ];
        $fields = ['douyin_user_id','mobile'];
        $first = DouyinUser::getInstance()->getWhere($where)->select($fields)->first();
        if($first==false){
            throw new IndexException(4020,'抖音号数据不存在');
        }

        //发送抖音验证码
        //$first['mobile'] = $param['mobile'];
        $result = MCNApply::getInstance()->sendCode($first);

        return $result;
    }

    /**
     * 提交合作申请
     * @param $param
     * @return mixed
     * @throws IndexException
     */
    public function submitFirstApply($param)
    {
        $lock = Common::setnx('submitFirstApply_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }
//        if(Common::checkMobile($param['mobile'])==false){
//            throw new IndexException(4020,'抖音手机号码错误');
//        }

        //todo 1 检查验证码
        $this->checkDouYinAuthCode($param);

        //todo 2 检查这个抖音号是否是未合作
        $filed = ['douyin_user_id','avatar','nickname','mobile','douyin_uid','fans_number','status'];
        $douYinUser = DouyinUser::getInstance()->getWhere(['douyin_user_id'=>$param['douyin_user_id']])->first($filed);
        if($douYinUser==false){
            throw new IndexException(4020,'请先授权抖音号');
        }

        $cooperateFirst = DouyinUserCooperate::getInstance()->getWhere(['douyin_user_id'=>$param['douyin_user_id'],'isdel'=>0])->first();
        if($cooperateFirst){
            try{
                DB::beginTransaction();
                $cooperateFirst->user_sn = request()->curUserId;
                $cooperateFirst->avatar = $douYinUser['avatar'];
                $cooperateFirst->nickname = $douYinUser['nickname'];
                $cooperateFirst->mobile = $douYinUser['mobile'];
                $cooperateFirst->settlement_image = $param['settlement_image'];
                $cooperateFirst->douyin_uid = $douYinUser['douyin_uid'];
                $cooperateFirst->status = 1;
                $cooperateFirst->save();

                $douYinUser->status = 2;
                //$douYinUser->mobile = $douYinUser['mobile'];
                $douYinUser->save();

                DB::commit();

                $douYinUser['cooperate_id'] = $cooperateFirst['cooperate_id'];
                return $douYinUser;
            }catch (IndexException $e){
                DB::rollBack();
                throw $e;
            }
        }else{
            $insert = [
                'user_sn'=>request()->curUserId,
                'douyin_user_id'=>$param['douyin_user_id'],
                'avatar'=>$douYinUser['avatar'],
                'nickname'=>$douYinUser['nickname'],
                'douyin_uid'=>$douYinUser['douyin_uid']??'',
                'mobile'=>$douYinUser['mobile'],
                'settlement_image'=>$param['settlement_image'],
                'truename'=>$param['truename']??'',
                'weixin_account'=>$param['weixin_account']??'',
                'user_mobile'=>$param['user_mobile']??'',
                'createtime'=>date('Y-m-d H:i:s'),
                'updatetime'=>date('Y-m-d H:i:s'),
                'status'=>1,
            ];
            try{
                DB::beginTransaction();
                $result = DouyinUserCooperate::getInstance()->insertGetId($insert);

                $douYinUser->status = 2;
                //$douYinUser->mobile = $douYinUser['mobile'];
                $douYinUser->save();

                DB::commit();

                $douYinUser['cooperate_id'] = $result;
                return $douYinUser;
            }catch (IndexException $e){
                DB::rollBack();
                throw $e;
            }
        }
    }

    protected function checkDouYinAuthCode($param)
    {
        $where = [
            'user_sn'=>request()->curUserId,
            'douyin_user_id'=>$param['douyin_user_id'],
        ];

        $first = DouyinUser::getInstance()->getWhere($where)->first();
        if($first==false){
            throw new IndexException(4020,'抖音号数据不存在');
        }

        if($first['is_bind_true']==1){
            return [
                "st"     => 0,
                "code"   => 0,
                "msg"    => "success",
                "log_id" => "20230904160841ABD57CB47FDD13149203",
                "data"   => [
                    "fans_number" => $first['fans_number'],
                    "user_id"     => $first['douyin_uid'],
                    "app_id"      => 1128,
                    "user_name"   => $first['nickname'],
                    "avatar_img"  => $first['avatar'],
                ]
            ];
        }

       // $first['mobile'] = $param['mobile'];
        $isSend = cache()->get('douyin_auth_apply_code_'.$first['mobile']);
        if($isSend==false){
            throw new IndexException(4020,'验证码已过期,请重新发送验证码');
        }

        //验证抖音验证码和确认抖音号
        $first['auth_code'] = $param['authcode'];
        $result = MCNApply::getInstance()->checkCode($first);

        if(empty($result['data']['ticket'])){
            throw new IndexException(4020,'验证码错误');
        }

        $first['ticket'] = $result['data']['ticket'];
        $result = MCNApply::getInstance()->getUserInfo($first);

        if(!empty($result['data']['user_id'])){
            //检查是否有电商权限
            MCNApply::getInstance()->authorBindCheck(['user_id'=>$result['data']['user_id']]);
            $update = [
                'is_bind_true'=>!empty($result['data']['user_id'])?1:0,
                'douyin_uid'=>!empty($result['data']['user_id'])?$result['data']['user_id']:'',
                'fans_number'=>!empty($result['data']['fans_number'])?$result['data']['fans_number']:'0',
            ];
            DouyinUser::getInstance()->getWhere(['douyin_user_id'=>$first['douyin_user_id']])->update($update);
        }

        return $result;
    }

    public function sendApplyBind($param)
    {
        $lock = Common::setnx('sendApplyBind_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }

        $where = [
            'isdel'=>0,
            'user_sn'=>request()->curUserId,
            'cooperate_id'=>$param['cooperate_id'],
        ];
        $fields = ['cooperate_id','douyin_user_id','mobile','douyin_uid','status'];
        $first = DouyinUserCooperate::getInstance()->getWhere($where)->select($fields)->first();
        if($first==false){
            throw new IndexException(4020,'合作数据不存在');
        }
        if($first['status']!=1){
            throw new IndexException(4020,'不是申请中状态');
        }

        //发送机账号构绑定申请
        $result = MCNApply::getInstance()->sendApplyBind($first);

        return $result;
    }

    public function sendSettlementBind($param)
    {
        $lock = Common::setnx('sendSettlementBind_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }

        $where = [
            'isdel'=>0,
            'user_sn'=>request()->curUserId,
            'cooperate_id'=>$param['cooperate_id'],
        ];
        $fields = ['cooperate_id','douyin_user_id','mobile','douyin_uid','status'];
        $first = DouyinUserCooperate::getInstance()->getWhere($where)->select($fields)->first();
        if($first==false){
            throw new IndexException(4020,'合作数据不存在');
        }
        if($first['status']!=1){
            throw new IndexException(4020,'不是申请中状态');
        }

        //发送机构结算绑定申请
        $result = MCNApply::getInstance()->sendSettlementBind($first);

        return $result;
    }

    public function submitAuthorize($param)
    {
        $lock = Common::setnx('submitAuthorize_'.request()->curUserId);
        if($lock==false){
            throw new IndexException(4020,'请求过于频繁');
        }

        $where = [
            'isdel'=>0,
            'user_sn'=>request()->curUserId,
            'cooperate_id'=>$param['cooperate_id'],
        ];

        $first = DouyinUserCooperate::getInstance()->getWhere($where)->first();
        if($first==false){
            throw new IndexException(4020,'合作数据不存在');
        }
        if($first['status']!=1){
            throw new IndexException(4020,'不是申请中状态');
        }

        $statusMap = $this->checkAuthorizeStatus($first);
        //检查当前账号是否已经绑定
        if($statusMap['status']==0){
            throw new IndexException(4020,'没有账号授权');
        }

        //检查当前结算是否已经绑定
        if($statusMap['status']==1){
            throw new IndexException(4020,'没有结算授权');
        }

        $first->status = 2;
        $first->sign_image = $param['sign_image'];
        $first->updatetime = date('Y-m-d H:i:s');
        $first->save();

        return true;
    }

    public function getAuthorizeList()
    {
        $where = [
            'isdel'=>0,
            'user_sn'=>request()->curUserId,
        ];
        $fields = ['cooperate_id','douyin_user_id','avatar','nickname','createtime','status'];
        $order = ['createtime','desc'];
        $data = DouyinUserCooperate::getInstance()->index($where,$fields,$order);

        $douYinMap = $this->getListMapById(DouyinUser::getInstance(),$data['data']->toArray(),'douyin_user_id','douyin_user_id',
                                        ['field'=>['douyin_user_id','fans_number']]);
        foreach($data['data'] as $val){
            $val->fans_number = !empty($douYinMap[$val['douyin_user_id']])?$douYinMap[$val['douyin_user_id']]['fans_number']:'0';
        }

        return $data;
    }

    public function getAuthorizeStatus()
    {
        $where = [
            'isdel'=>0,
            'user_sn'=>request()->curUserId,
        ];
        $fields = ['cooperate_id','douyin_user_id','avatar','nickname','createtime','status'];
        $order = ['createtime','desc'];
        $data = DouyinUserCooperate::getInstance()->index($where,$fields,$order);

        $status = 0;
        foreach($data['data'] as $val){
           if($val['status']==3){
               $status = 1;
               break;
           }
        }

        return ['status'=>$status];
    }
}